home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Disc to the Future 2
/
Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin
/
MAC
/
THINKC
/
4_0
/
UPFKEY__
/
UP_FKEY.C
Wrap
C/C++ Source or Header
|
1990-02-10
|
5KB
|
167 lines
/*
* Here's the plan:
* 1. post a double-click in the title bar of the frontmost window
* 2. wait for the parent window to appear
* 3. select the second window
* 4. post a COMMAND-W
*
* The problem here is between step 2 and 3. If we leave the FKEY to let
* the Finder bring forth the parent window after step 2, we aren't around
* to perform step 3. Note that we can't get the Finder to do step 3 by
* posting a mouse down event in the second window because the second
* window may be completely covered by the first window.
*
* This leads to the modified plan:
*
* 1. post a double-click in the title bar of the frontmost window
* 2. post a COMMAND-SHIFT-NUMBER keyboard event, where NUMBER is
* the number of this FKEY
* 3. Return to Finder
* 4. Finder makes parent window appear
* 5. COMMAND-SHIFT-NUMBER is processed, bringing us back to the FKEY
* 6. select the second window
* 7. post a COMMAND-W
*
* Now we have a different problem. The FKEY is invoked twice. Since it has
* no global variables that will stick around between the two invocations, how
* to we tell them apart? We will let the user do it for us! The first time
* around, we will wait for the user to release one of the COMMAND, SHIFT, or
* NUMBER keys before returning to the Finder. This lets us tell which pass we
* are on: if the keys are down, it is the first pass; if they are up, it is
* the second pass.
*
* This leads to the final plan of attack:
*
* 1. Check the keyboard status to see which pass we are on
* 2. if first pass, then
* 2a. post a double-click in title bar of front window
* 2b. post keyboard events to reinvoke FKEY
* 2c. post COMMAND-W
* 2d. wait for user to release key
* 2e. return to Finder
* 3. else
* 3a. select second window
* 3b. return to Finder
*/
void main( void );
void begin( void );
/*
* When we are invoked for the first time, STILL_DOWN will be true.
* When the user releases one of the keys, STILL_DOWN will become false.
*/
#define STILL_DOWN (*(unsigned short *)0x184 != 0)
/*
* Begin is here to get the proper FKEY header. Make sure you have
* the custom header option checked in Think C!
*/
void begin()
{
asm
{
bra.s @1
dc.w 0
dc.b 'F','K','E','Y'
@OurID:
dc.w 6
dc.w 0
@1: lea begin, A4
pea main ; I have no idea why I didn't use jmp...
rts
}
}
void main()
{
long p;
long * pp;
GrafPtr savePort;
if ( ! STILL_DOWN )
{
/*
* Second pass. We need to get the window zapped.
*/
WindowPeek front;
front = (WindowPeek)FrontWindow();
if ( front == 0 )
return;
/*
* If the second window is "reasonable", we will select it and let
* the COMMAND-W zap it. If it is not reasonable, then the user
* probably did something like try to move up from the root.
* In this case, we get rid of the COMMAND-W.
*/
if ( front->nextWindow != 0 && front->nextWindow->visible )
SelectWindow( front->nextWindow );
else
FlushEvents( keyDownMask|keyUpMask, 0 );
return;
}
/*
* First pass. First step is to find the title bar of the front window
*/
pp = (long *)FrontWindow();
GetPort( &savePort );
SetPort( pp ); /* so LocalToGlobal will work like we want */
p = pp[4]; /* top left of window... */
LocalToGlobal( &p ); /* ...in global co-ords */
SetPort( savePort );
asm
{
;
; make PostEvent think that the mouse is in the title bar
;
move.l 0x830,-(a7) ; this is where _PostEvent gets the mouse
; ...location from. We are going to
; ..."borrow" it.
move.l p, d0 ; Co-ords of top left of window
add.w #4, d0 ; We compute the co-ords of
swap d0 ; ...a point 4 pixels over
sub.w #4, d0 ; ...and 4 pixels up. This
swap d0 ; ...is where we will put our
move.l d0, 0x830 ; ...imaginary mouse
;
; Now we can post the double-click!
;
move.w 0x17a,-(a7) ; These are where _PostEvent gets the state
move.w 0x184,-(a7) ; ...of the keyboard.
move.w #0,0x17a ; We want _PostEvent to think that no keys
move.w #0,0x184 ; ...are pressed.
move #1, a0
_PostEvent ; mouse down
move #2, a0
_PostEvent ; mouse up
move #1, a0
_PostEvent ; mouse down
move #2, a0
_PostEvent ; mouse up
move.w (a7)+,0x184 ; we can stop lying to _PostEvent now
move.w (a7)+,0x17a
move.l (a7)+,0x830
;
; The shift and command keys should still be down from the original
; invocation of this FKEY
;
move.w #3, a0 ; key down
move.w 0x184, d0
_PostEvent
move.w #4, a0 ; key up
move.w 0x184, d0
_PostEvent
move.w #3, a0 ; key down
move.l #0, d0
move.w #0x0d00|'W', d0
_PostEvent
move.w #4, a0 ; key up
move.l #0, d0
move.w #0x0d00|'W', d0
_PostEvent
}
while ( STILL_DOWN )
;
}